﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Mozlite.FileStorages;
using Mozlite.FileStorages.Editors.KindEditor;
using Mozlite.Common;
using System.Drawing.Imaging;
using System.IO;
using Mozlite.Cryptography;

namespace Mozlite.Web.UI.Areas.UCenter.Controllers
{
    public class DialogController : UCenterBaseController
    {
        private UserFolder GetFolder(bool bNew = false)
        {
            int folderID = Request.QueryString["id"].ToInt32();
            UserFolder folder;
            if (!Storages.GetFolders().TryGetValue(folderID, out folder))
            {
                if (bNew)
                    folder = new UserFolder();
                else
                    SetResourceStatus(FileStorageStatus.FolderNotFound);
            }
            return folder;
        }

        public ActionResult FolderView()
        {
            return View(GetFolder(true));
        }

        [HttpPost]
        public ActionResult FolderView(UserFolder model)
        {
            if (ModelState.IsValid)
            {
                UserFolder folder = new UserFolder();
                folder.FolderID = Request.QueryString["id"].ToInt32();
                folder.FolderName = model.FolderName;
                folder.ParentID = model.ParentID;
                folder.UserID = Self.UserID;
                var status = Storages.CreateFolder(folder);
                SetResourceStatus(status, status != FileStorageStatus.Created && status != FileStorageStatus.Updated);
            }
            return View(model);
        }

        public ActionResult UpdateFolderView()
        {
            return View(GetFolder());
        }

        [HttpPost]
        public ActionResult UpdateFolderView(UserFolder model)
        {
            if (ModelState.IsValid)
            {
                UserFolder folder = GetFolder();
                if (folder != null)
                {
                    if (!model.FolderName.IsMatched(folder.FolderName) && !folder.Parent.IsNameValided(model.FolderName))
                    {
                        SetResourceStatus(FileStorageStatus.DuplicateFolderName, false);
                    }
                    else
                    {
                        model.FolderID = folder.FolderID;
                        model.UserID = folder.UserID;
                        var status = Storages.ChangeFolderName(model);
                        SetResourceStatus(status, status != FileStorageStatus.Updated);
                    }
                }
            }
            return View(model);
        }

        public ActionResult MoveFolderView()
        {
            return View(GetFolder());
        }

        [HttpPost]
        public ActionResult MoveFolderView(UserFolder model)
        {
            if (ModelState.IsValid)
            {
                UserFolder folder = GetFolder();
                if (folder != null)
                {
                    var status = Storages.MoveFolder(folder.FolderID, model.ParentID);
                    SetResourceStatus(status, status != FileStorageStatus.Moved);
                }
            }
            return View(model);
        }

        private UserFile GetFile(bool bNew = false)
        {
            var file = Storages.GetFile(Request.QueryString["id"].ToInt32());
            if (file == null)
            {
                if (bNew)
                    file = new UserFile();
                else
                    SetResourceStatus(FileStorageStatus.FileNotFound);
            }
            return file;
        }

        public ActionResult MoveFileView()
        {
            return View(GetFile());
        }

        [HttpPost]
        public ActionResult MoveFileView(UserFile model)
        {
            if (ModelState.IsValid)
            {
                var fileID = Request.QueryString["id"].ToInt32();
                var status = Storages.MoveFile(fileID, model.FolderID);
                SetResourceStatus(status, status != FileStorageStatus.Moved);
            }
            return View(model);
        }

        public ActionResult UpdateFileView()
        {
            return View(GetFile());
        }

        [HttpPost]
        public ActionResult UpdateFileView(UserFile model, FormCollection form)
        {
            UserFile file = GetFile();
            if (ModelState.IsValid)
            {
                if (file != null)
                {
                    file.SetFileName(form["FullName"]);
                    file.FolderID = model.FolderID;
                    UserFolder folder;
                    if (!Storages.GetFolders().TryGetValue(file.FolderID, out folder))
                        folder = new UserFolder();
                    if (!folder.IsNameValided(file.FullName))
                    {
                        SetResourceStatus(FileStorageStatus.DuplicateFileName, true);
                        return View(file);
                    }
                    if (!Permission.IsFileAllowed(file.Extension))
                    {
                        SetResourceStatus(FileStorageStatus.InvalidExtension, true, Permission.AllowableExtensions);
                        return View(file);
                    }
                    var status = Storages.SaveFile(file);
                    SetResourceStatus(status, status != FileStorageStatus.Updated);
                }
            }
            return View(file);
        }

        public ActionResult DiskView()
        {
            ViewBag.FileType = this.Get<FileType>("type");
            return View(GetFolder(true));
        }

        [HttpPost]
        public ActionResult DiskView(FormCollection form)
        {
            ViewBag.FileType = this.Get<FileType>("type");
            var folder = GetFolder();
            if (ModelState.IsValid)
            {
                switch (form.GetAction())
                {
                    case HttpAction.File:
                        {
                            int did = form.Get<int>("did");
                            return DeleteFile(did);
                        }
                    case HttpAction.Folder:
                        {
                            int did = form.Get<int>("did");
                            return DeleteFolder(did);
                        }
                    default:
                        return UploadFile(folder);
                }
            }
            return View(folder);
        }

        [HttpPost]
        public JsonResult UploadView(FormCollection form)
        {
            if (Permission.AllowUpload != true)
            {
                return Json(new { error = 1, message = Local(FileStorageStatus.AccessDisabled) });
            }
            var postedFile = Request.Files["imgFile"];
            if (postedFile != null && postedFile.ContentLength > 0)
            {
                UserFolder folder = Storages.GetFolderFromCache(SelfProfile.FolderID);
                var file = new UserFile(postedFile, folder.FolderID);
                if (!folder.IsNameValided(file.FullName))
                {
                    return Json(new { error = 1, message = Local(FileStorageStatus.DuplicateFileName) });
                }
                if (!Permission.IsFileAllowed(file.Extension))
                {
                    return Json(new { error = 1, message = Local(FileStorageStatus.InvalidExtension, Permission.AllowableExtensions) });
                }
                if (file.ContentLength > Permission.MaxSingleFileLength)
                {
                    return Json(new { error = 1, message = Local(FileStorageStatus.SingleFileSizeError, Permission.MaxSingleFileLength.ToContentLengthString()) });
                }
                if (Storages.GetDiskUsage() + file.ContentLength > Permission.MaxDiskSize)
                {
                    return Json(new { error = 1, message = Local(FileStorageStatus.DiskFileSizeError, Permission.MaxDiskSize.ToContentLengthString()) });
                }
                file.SaveAsTemp();
                FileStorageStatus status = Storages.SaveFile(file);
                if (status == FileStorageStatus.Created)
                {
                    file.Completed();
                    folder.Refresh();
                    return Json(new { error = 0, url = GetFileBrowserUrl(file.FileID), title = file.FullName });
                }
                return Json(new { error = 1, message = Local(status) });
            }
            return Json(new { error = 1, message = Local(FileStorageStatus.FileNotFound) });
        }

        public JsonResult FileManager()
        {
            if (Permission.AllowFileBrowser == true)
            {
                UserFolder folder = Storages.GetFolderFromCache(this.Get<int>("id", SelfProfile.FolderID));
                var browser = new BrowserDir(folder, this.Get<StorageSortOrder>("order"), this.Get<FileType>("dir"));
                browser.current_url = GetFileBrowserUrl();
                browser.current_dir_path = folder.FolderID.ToString();
                browser.moveup_dir_path = folder.ParentID.ToString();
                return Json(browser, JsonRequestBehavior.AllowGet);
            }
            return Json(null);
        }

        public ActionResult ImageView()
        {
            var file = GetFile();
            if (file == null || file.FileType != FileType.Image)
            {
                SetResourceStatus(FileStorageStatus.NotImage);
            }
            return View(file);
        }

        [HttpPost]
        public ActionResult ImageView(UserFile model, FormCollection form)
        {
            if (ModelState.IsValid)
            {
                var file = GetFile();
                if (file == null || file.FileType != FileType.Image)
                {
                    SetResourceStatus(FileStorageStatus.NotImage);
                    return View(file);
                }
                string fileName = Globals.GetNewTempPath();
                Globals.SaveImage(file.Path, form.Get<int>("ImageWidth"), form.Get<int>("ImageHeight"), f =>
                {
                    return fileName;
                });
                var folder = Storages.GetFolderFromCache(model.FolderID);
                var fileInfo = new FileInfo(fileName);
                model.SetFileName(form.Get<string>("FullName"));
                model.ContentLength = fileInfo.Length;
                if (!folder.IsNameValided(model.FullName))
                {
                    SetResourceStatus(FileStorageStatus.DuplicateFileName, true);
                    return View(folder);
                }
                if (!Permission.IsFileAllowed(model.Extension))
                {
                    SetResourceStatus(FileStorageStatus.InvalidExtension, true, Permission.AllowableExtensions);
                    return View(folder);
                }
                if (model.ContentLength > Permission.MaxSingleFileLength)
                {
                    SetResourceStatus(FileStorageStatus.SingleFileSizeError, true, Permission.MaxSingleFileLength.ToContentLengthString());
                    return View(folder);
                }
                if (Storages.GetDiskUsage() + model.ContentLength > Permission.MaxDiskSize)
                {
                    SetResourceStatus(FileStorageStatus.DiskFileSizeError, true, Permission.MaxDiskSize.ToContentLengthString());
                    return View(folder);
                }
                model.ContentType = file.ContentType;
                model.DiskFileID = Cryptors.GetHex(Cryptors.BatchMake(fileName, EncryptionAlgorithm.MD5));
                model.Extension = file.Extension;
                model.FileType = FileType.Image;
                model.UserID = file.UserID;
                FileStorageStatus status = Storages.SaveFile(model);
                if (status == FileStorageStatus.Created)
                {
                    model.Completed(fileName);
                    folder.Refresh();
                }
                SetResourceStatus(status, status != FileStorageStatus.Created);
            }
            return View(model);
        }
    }
}
